package demo.webauthn.config;

import com.yubico.webauthn.CredentialRepository;
import com.yubico.webauthn.RegisteredCredential;
import com.yubico.webauthn.data.ByteArray;
import com.yubico.webauthn.data.PublicKeyCredentialDescriptor;
import demo.webauthn.domain.WebAuthUser;
import demo.webauthn.mapper.WebAuthUserMapper;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Getter
@Repository
public class RegistrationService implements CredentialRepository {

    @Autowired
    private WebAuthUserMapper webAuthUserMapper;

    @Override
    public Set<PublicKeyCredentialDescriptor> getCredentialIdsForUsername(String username) {

        List<WebAuthUser> WebAuthUsers = webAuthUserMapper.selectByUsername(username);
        return WebAuthUsers.stream()
                .map(
                        WebAuthUser ->
                                PublicKeyCredentialDescriptor.builder()
                                        .id(ByteArray.fromBase64(WebAuthUser.getCredentialId()))
                                        .build())
                .collect(Collectors.toSet());
    }

    @Override
    public Optional<ByteArray> getUserHandleForUsername(String username) {
        List<WebAuthUser> WebAuthUsers = webAuthUserMapper.selectByUsername(username);
        return Optional.of(ByteArray.fromBase64(WebAuthUsers.get(0).getAlgorithm()));
    }

    @Override
    public Optional<String> getUsernameForUserHandle(ByteArray userHandle) {
        List<WebAuthUser> WebAuthUsers = webAuthUserMapper.selectByAlgorithm(userHandle.getBase64());
        return Optional.of(WebAuthUsers.get(0).getUserName());
    }

    @Override
    public Optional<RegisteredCredential> lookup(ByteArray credentialId, ByteArray userHandle) {
        WebAuthUser WebAuthUsers = webAuthUserMapper.selectOneByCredentialIdAndAlgorithm(credentialId.getBase64(), userHandle.getBase64());
        Optional<WebAuthUser> auth = Optional.of(WebAuthUsers);
        return auth.map(
                credential ->
                        RegisteredCredential.builder()
                                .credentialId(ByteArray.fromBase64(credential.getCredentialId()))
                                .userHandle(ByteArray.fromBase64(credential.getAlgorithm()))
                                .publicKeyCose(ByteArray.fromBase64(credential.getPublicKey()))
//                                .signatureCount(credential.getCount())
                                .build()
        );
    }

    @Override
    public Set<RegisteredCredential> lookupAll(ByteArray credentialId) {
        List<WebAuthUser> auth = webAuthUserMapper.selectByCredentialId(new String(credentialId.getBytes()));
        return auth.stream()
                .map(
                        credential ->
                                RegisteredCredential.builder()
                                        .credentialId(ByteArray.fromBase64(credential.getCredentialId()))
                                        .userHandle(ByteArray.fromBase64(credential.getAlgorithm()))
                                        .publicKeyCose(ByteArray.fromBase64(credential.getPublicKey()))
//                                        .signatureCount(credential.getCount())
                                        .build())
                .collect(Collectors.toSet());
    }
}
